package com.filetransfer.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.filetransfer.dao.DeviceMapper;
import com.filetransfer.dao.FileTransferMapper;
import com.filetransfer.model.dto.FileTransferDTO;
import com.filetransfer.model.entity.Device;
import com.filetransfer.model.entity.FileTransfer;
import com.filetransfer.service.FileTransferService;
import com.filetransfer.util.FileUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 文件传输服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FileTransferServiceImpl implements FileTransferService {

    private final FileTransferMapper fileTransferMapper;
    private final DeviceMapper deviceMapper;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createFileTransfer(FileTransferDTO fileTransferDTO) {
        FileTransfer fileTransfer = new FileTransfer();
        BeanUtils.copyProperties(fileTransferDTO, fileTransfer);
        
        // 如果没有设置接收者ID，设置一个临时值
        if (fileTransfer.getReceiverId() == null) {
            fileTransfer.setReceiverId("pending");
        }
        
        // 如果没有传输密钥，则生成一个
        if (fileTransfer.getTransferKey() == null || fileTransfer.getTransferKey().isEmpty()) {
            String transferKey = generateTransferKey();
            fileTransfer.setTransferKey(transferKey);
        }
        
        // 设置默认状态和时间
        fileTransfer.setStatus(0); // 等待接收
        LocalDateTime now = LocalDateTime.now();
        fileTransfer.setCreateTime(now);
        fileTransfer.setUpdateTime(now);
        
        fileTransferMapper.insert(fileTransfer);
        return fileTransfer.getId();
    }
    
    @Override
    public boolean updateStatus(Long id, Integer status) {
        LambdaUpdateWrapper<FileTransfer> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(FileTransfer::getId, id)
                .set(FileTransfer::getStatus, status)
                .set(FileTransfer::getUpdateTime, LocalDateTime.now());
        
        return fileTransferMapper.update(null, updateWrapper) > 0;
    }
    
    @Override
    public boolean updateStatusAndReceiver(Long id, Integer status, String receiverId, String receiverName) {
        LambdaUpdateWrapper<FileTransfer> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(FileTransfer::getId, id)
                .set(FileTransfer::getStatus, status)
                .set(FileTransfer::getReceiverId, receiverId)
                .set(FileTransfer::getUpdateTime, LocalDateTime.now());
        
        boolean result = fileTransferMapper.update(null, updateWrapper) > 0;
        
        // 更新成功后，记录接收者名称（由于实体中可能没有receiverName字段，在DTO转换时处理）
        if (result && receiverId != null && !receiverId.equals("pending")) {
            // 获取接收者设备，可能需要更新设备名称
            Device receiver = deviceMapper.selectById(receiverId);
            if (receiver != null && !receiverName.equals(receiver.getDeviceName())) {
                receiver.setDeviceName(receiverName);
                deviceMapper.updateById(receiver);
            }
        }
        
        return result;
    }
    
    @Override
    public FileTransferDTO getById(Long id) {
        FileTransfer fileTransfer = fileTransferMapper.selectById(id);
        return fileTransfer != null ? convertToDTO(fileTransfer) : null;
    }
    
    @Override
    public FileTransferDTO getByTransferKey(String transferKey) {
        LambdaQueryWrapper<FileTransfer> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FileTransfer::getTransferKey, transferKey);
        
        FileTransfer fileTransfer = fileTransferMapper.selectOne(queryWrapper);
        return fileTransfer != null ? convertToDTO(fileTransfer) : null;
    }
    
    @Override
    public List<FileTransferDTO> getSentFileTransfers(String senderId) {
        LambdaQueryWrapper<FileTransfer> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FileTransfer::getSenderId, senderId)
                .orderByDesc(FileTransfer::getCreateTime);
        
        return fileTransferMapper.selectList(queryWrapper)
                .stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public List<FileTransferDTO> getReceivedFileTransfers(String receiverId) {
        LambdaQueryWrapper<FileTransfer> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FileTransfer::getReceiverId, receiverId)
                .orderByDesc(FileTransfer::getCreateTime);
        
        return fileTransferMapper.selectList(queryWrapper)
                .stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public List<FileTransferDTO> getFileTransfersBetween(String deviceId1, String deviceId2) {
        LambdaQueryWrapper<FileTransfer> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.and(wrapper -> wrapper
                .and(w -> w
                        .eq(FileTransfer::getSenderId, deviceId1)
                        .eq(FileTransfer::getReceiverId, deviceId2))
                .or(w -> w
                        .eq(FileTransfer::getSenderId, deviceId2)
                        .eq(FileTransfer::getReceiverId, deviceId1)))
                .orderByDesc(FileTransfer::getCreateTime);
        
        return fileTransferMapper.selectList(queryWrapper)
                .stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public FileTransferDTO convertToDTO(FileTransfer fileTransfer) {
        if (fileTransfer == null) {
            return null;
        }
        
        FileTransferDTO fileTransferDTO = new FileTransferDTO();
        BeanUtils.copyProperties(fileTransfer, fileTransferDTO);
        
        // 获取发送者和接收者名称
        Device sender = deviceMapper.selectById(fileTransfer.getSenderId());
        Device receiver = deviceMapper.selectById(fileTransfer.getReceiverId());
        
        if (sender != null) {
            fileTransferDTO.setSenderName(sender.getDeviceName());
        }
        
        if (receiver != null) {
            fileTransferDTO.setReceiverName(receiver.getDeviceName());
        }
        
        // 格式化文件大小
        fileTransferDTO.setFileSizeFormatted(FileUtil.formatFileSize(fileTransfer.getFileSize()));
        
        // 设置状态描述
        fileTransferDTO.setStatusDesc(getStatusDesc(fileTransfer.getStatus()));
        
        return fileTransferDTO;
    }
    
    /**
     * 生成传输密钥
     * @return 密钥
     */
    private String generateTransferKey() {
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 8);
    }
    
    /**
     * 获取状态描述
     * @param status 状态
     * @return 状态描述
     */
    private String getStatusDesc(Integer status) {
        if (status == null) {
            return "未知";
        }
        
        switch (status) {
            case 0: return "等待接收";
            case 1: return "传输中";
            case 2: return "已完成";
            case 3: return "已取消";
            case 4: return "传输失败";
            default: return "未知";
        }
    }
} 